package com.eling.elcms.travel.service.impl;

import com.eling.elcms.core.service.ServiceLocator;
import com.eling.elcms.core.service.impl.GenericManagerImpl;
import com.eling.elcms.travel.dao.ICheckOutSettlementDao;
import com.eling.elcms.travel.model.*;
import com.eling.elcms.travel.model.CheckInImplement.DataSource;
import com.eling.elcms.travel.model.view.SettlementsResult;
import com.eling.elcms.travel.service.*;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
public class CheckOutSettlementManagerImpl extends GenericManagerImpl<CheckOutSettlement, Long>
		implements ICheckOutSettlementManager {

	ICheckOutSettlementDao checkOutSettlementDao;

	@Autowired
	private ITravelContractManager contractM;
	@Autowired
	private IBasePriceManager basePriceManager;
	@Autowired
	private ICarDispatchManager carDispatchManager;
	@Autowired
	private ICheckInImplementManager checkInImplementManager;

	@Autowired
	public void setCheckOutSettlementDao(ICheckOutSettlementDao checkOutSettlementDao) {
		this.dao = checkOutSettlementDao;
		this.checkOutSettlementDao = checkOutSettlementDao;
	}

	@Override
	public SettlementsResult getMemberRuleMoney(RoomPersonalInfo roomPerson, RuleType type, Date checkinDate,
			Date checkoutDate) {
		Boolean flag = true;
		TravelContract contract = new TravelContract();
		if (!roomPerson.getCheckInImplement().getDataSource().equals(DataSource.GroupReserve)) {
			flag = false;
			contract = roomPerson.getNonMemberRegister().getSignUpRegister().getTravelContract();
		} else {
			contract = roomPerson.getSignUpRegister().getTravelContract();
		}
		// 入住人员的权证信息不为空，则是内部会员，内部会员入住直属机构，规则范围全能适用
		if (contract != null) {
			// 抵扣范围匹配时计算抵扣份数及金额
			SettlementsRule rule = contractM.getContractSetlRuleByType(
					!flag ? roomPerson.getNonMemberRegister().getSignUpRegister().getTravelContract()
							: roomPerson.getSignUpRegister().getTravelContract(),
					type);
			if (rule != null) {
				// 获取对应的规则实现类
				ISettlementsRule ruleImpl = ServiceLocator.getService(rule.getServiceImpl());
				// 返回合同对应规则的本次抵扣、消费卷、其他的金额
				return ruleImpl.calculate(roomPerson.getRoomRegister(), contract, checkinDate, checkoutDate);
			} else {
				return new SettlementsResult();
			}
		} else {
			return new SettlementsResult();
		}
	}

	@Override
	public CheckOutSettlement createCheckOutSettlement(RoomPersonalInfo roomPersonalInfo, Double roomPrice, Integer num,
			Date checkinDate, Date checkoutDate) {
		BasePrice basePrice = basePriceManager.getPrice();
		CheckOutSettlement checkOutSettlement = new CheckOutSettlement();
		RoomRegister roomRegister = roomPersonalInfo.getRoomRegister();
		if (roomPersonalInfo.getCheckOutSettlement() != null
				&& roomPersonalInfo.getCheckOutSettlement().getPkCheckOutSettlement() != null) {
			checkOutSettlement = roomPersonalInfo.getCheckOutSettlement();
		}
		double electric = 0.0;
		double coldWater = 0.0;
		double hotWater = 0.0;

		if (roomRegister.getWaterElectric() != null && !roomRegister.getWaterElectric()) {
			electric = (roomRegister.getCheckOutElectricMeter() - roomRegister.getElectricMeter())
					* basePrice.getElectric() / num;
			coldWater = (roomRegister.getCheckOutWaterMeter() - roomRegister.getWaterMeter()) * basePrice.getWater()
					/ num;
			hotWater = (roomRegister.getCheckOutHotWaterMeter() - roomRegister.getHotWaterMeter())
					* basePrice.getHotWater() / num;
		}
		checkOutSettlement.setRoom(roomPrice / num);
		checkOutSettlement.setElectric(electric);
		checkOutSettlement.setColdWater(coldWater);
		checkOutSettlement.setHotWater(hotWater);
		if (roomPersonalInfo.getCheckInImplement().getDataSource().equals(DataSource.GroupReserve)) {
			if (roomPersonalInfo.getSignUpRegister() != null
					&& roomPersonalInfo.getSignUpRegister().getTravelContract() != null) {
				Double expense = getMemberRuleMoney(roomPersonalInfo, RuleType.Expense, checkinDate, checkoutDate)
						.getMoney();
				checkOutSettlement.setExpense(expense == null ? 0.0 : expense);
			}
		} else {
			if (roomPersonalInfo.getNonMemberRegister() != null
					&& roomPersonalInfo.getNonMemberRegister().getSignUpRegister().getMember()) {
				Double expense = getMemberRuleMoney(roomPersonalInfo, RuleType.Expense, checkinDate, checkoutDate)
						.getMoney();
				checkOutSettlement.setExpense(expense == null ? 0.0 : expense);
			}
		}

		SettlementsResult bedResult = getMemberRuleMoney(roomPersonalInfo, RuleType.BedSubsidy, checkinDate,
				checkoutDate);
		// 如果抵扣单位不为空且不为0说明用的按天抵扣规则
		if (bedResult.getPiece() != null && bedResult.getPiece() != 0D) {
			// 分摊后的房费全额抵扣
			checkOutSettlement.setBedSubsidy(checkOutSettlement.getRoom());
			checkOutSettlement.setBedSubsidyUnit(bedResult.getPiece() / num);

		} else {
			checkOutSettlement.setBedSubsidy(bedResult.getMoney() == null ? 0.0 : bedResult.getMoney());
		}
		return save(checkOutSettlement);
	}

	@Override
	public CheckOutSettlement creatPickUp(CheckOutSettlement checkOutSettlement, CheckInImplement checkInImplement) {

		//防止懒加载
		checkInImplement = checkInImplementManager.get(checkInImplement.getPkCIImplement());
		
		Integer signUpNum = checkInImplement.getSignUpNum();
		Double pickUpSum = 0.00;
		Double pickUpAverage = 0.00;
		if(checkInImplement.getDataSource().equals(DataSource.GroupReserve)){
			CarDispatchBill carDispatchBill = new CarDispatchBill();
			carDispatchBill.setGroupReserve(checkInImplement.getGroupReserve());
			List<CarDispatchBill> cdbList = carDispatchManager.query(carDispatchBill);
			if(CollectionUtils.isNotEmpty(cdbList)){
				for(CarDispatchBill cdb : cdbList){
					if(cdb.getTotalPrice() != null){
						pickUpSum += cdb.getTotalPrice();
					}
				}
			}
		}else{
			CarDispatchBill carDispatchBill = new CarDispatchBill();
			carDispatchBill.setNonMemGroupReserve(checkInImplement.getNonMemGroupReserve());
			List<CarDispatchBill> cdbList = carDispatchManager.query(carDispatchBill);
			if(CollectionUtils.isNotEmpty(cdbList)){
				for(CarDispatchBill cdb : cdbList){
					if(cdb.getTotalPrice() != null){
						pickUpSum += cdb.getTotalPrice();
					}
				}
			}
		}
		
		if(signUpNum != 0){
			pickUpAverage = pickUpSum/signUpNum;
		}
		checkOutSettlement.setPickUp(pickUpAverage);
		
		return save(checkOutSettlement);
	}
}
